﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Text;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Configuration;


/// <summary>
/// Summary description for DeviceInfo
/// </summary>
public class DeviceInfo //: IComparable<DeviceInfo>
{
    public long ID { get; set; }
    public string Plate { get; set; }
    public string Driver { get; set; }
    public string Cellphone { get; set; }
    public string Location { get; set; }
    public float Speed { get; set; }
    public byte Status { get; set; }    //0:Xe mat tin hieu: Mau xam
    //1:Xe mat GPS: Mau vang
    //2:Xe dang dung: Mau do
    //3:Xa dang chay: Mau xanh duong
    public string Time { get; set; }
    public string URL { get; set; }
    public double Longitude { get; set; } //kinh dộ
    public double Latitude { get; set; } //vi độ
    //public int CompareTo(DeviceInfo deviceinfo)
    //{
    //    return Convert.ToInt64(this.ID).CompareTo(Convert.ToInt64(deviceinfo.ID));
    //}
}

public class DeviceInfoRepository
{
    private static readonly byte[] MESSAGE_MARKER = { 0x23, 0x23, 0x0D, 0x0A };
    private static IPAddress IPAddress = IPAddress.Parse(ConfigurationManager.AppSettings["ServerAddress"]);
    private static int nPort = int.Parse(ConfigurationManager.AppSettings["ServerPort"]);
    private static IPEndPoint iep = new IPEndPoint(IPAddress, nPort);

    public DeviceInfoRepository()
    {

    }

    private Int64 Hexa2Decimal(Int64 nHexa)
    {
        return nHexa & 0x00ffffffffffffff;
    }

    public List<DeviceInfo> Select(Int32 devInfoID)
    {
        
        List<DeviceInfo> devInfoList = devInfoList = new List<DeviceInfo>();

        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        sock.Connect(iep);
        Message requestMsg = new Message((ushort)DeviceMessage.MC_MOBILE_DEVICE_LIST_INFO, 0, (int)devInfoID); //Lay Message theo id user
        if (requestMsg.Send(sock, MESSAGE_MARKER) != -1)
        {
            byte[] refBuffer = null;
            int nRefBufOffset = 0;
            int nRefBufSize = 0;
            int nCountLtd = 0;

            MessageQueue msgQueue = new MessageQueue();
            Message recvMsg = new Message();
            
            while (nCountLtd++ < 100000 &&
                sock.Connected &&
                !msgQueue.PopWebMessage(out refBuffer, out nRefBufOffset, out nRefBufSize))
            {
                msgQueue.Push(sock);
            }
            sock.Close();
            
            if (refBuffer != null && recvMsg.Parse(refBuffer, nRefBufOffset, nRefBufSize))
            {
                MemoryStream msr = new MemoryStream(recvMsg.Data, recvMsg.DataOffset, recvMsg.DataSize);
                BinaryReader br = new BinaryReader(msr);

                UnicodeEncoding Unicode = new UnicodeEncoding();
                int nCount, nStringSize;
                Int64 nDevID;
                double dLat, dLon;
                float fSpeed;
                byte nStatus;
                string szPlate, szDriverName, szTel, szDeviceName, szSerial, szSim, szTime;
                nCount = br.ReadInt32();

                for (int i = 0; i < nCount; i++)
                {
                    //MaTB.
                    nDevID = Hexa2Decimal(br.ReadInt64());

                    //BienSoXe.
                    nStringSize = br.ReadInt32();
                    szPlate = Unicode.GetString(br.ReadBytes(nStringSize));

                    //HoTenTX.
                    /*nStringSize = br.ReadInt32();
                    szDriverName = Unicode.GetString(br.ReadBytes(nStringSize));

                    //SoDienThoai.
                    nStringSize = br.ReadInt32();
                    szTel = Unicode.GetString(br.ReadBytes(nStringSize));

                    //TenTB.
                    nStringSize = br.ReadInt32();
                    szDeviceName = Unicode.GetString(br.ReadBytes(nStringSize));

                    //Serial.
                    nStringSize = br.ReadInt32();
                    szSerial = Unicode.GetString(br.ReadBytes(nStringSize));

                    //Sim.
                    nStringSize = br.ReadInt32();
                    szSim = Unicode.GetString(br.ReadBytes(nStringSize));*/

                    // ViDo.
                    dLat = br.ReadDouble();

                    // KinhDo.
                    dLon = br.ReadDouble();

                    //Speed.
                    fSpeed = br.ReadSingle();

                    //Status.
                    nStatus = br.ReadByte();

                    //ThoiGian.
                    nStringSize = br.ReadInt32();
                    szTime = Unicode.GetString(br.ReadBytes(nStringSize));
                    DateTime dateTime = DateTime.ParseExact(szTime, "dd/MM/yyyy HH:mm:ss", null);
                    dateTime = dateTime.AddHours(7.0);

                    DeviceInfo devInfo = new DeviceInfo();
                    devInfo.ID = nDevID;
                    devInfo.Plate = szPlate;
                    //devInfo.Driver = szDriverName;
                    //devInfo.Cellphone = szTel;
                    devInfo.Longitude = dLon;
                    devInfo.Latitude = dLat;
                    //devInfo.Location = dLat +"," + dLon;// String.Format("<a class=Address data-rel=dialog href=Map.aspx?lat={0}&lon={1}&level={2}&hw=", dLat, dLon, 15) + ">" + szLocation + "</a>";
                    devInfo.Time = dateTime.ToString("dd/MM/yyyy HH:mm:ss");
                    devInfo.Speed = fSpeed;
                    devInfo.Status = nStatus;
                    devInfoList.Add(devInfo);
                }
                br.Close();
                br.Dispose();
                msr.Close();
                msr.Dispose();
                // devInfoList.Sort();
                // HttpContext.Current.Session["DeviceInfoList"] = devInfoList;
            }


        }

        return devInfoList;
    }
    public void Insert(DeviceInfo devInfo)
    {
        // Implement Insert logic
    }
    public void Update(DeviceInfo devInfo)
    {
        // Implement Update logic
    }
    public void Delete(DeviceInfo devInfo)
    {
        // Implement Delete logic
    }


}
